package com.mfin.bs.mgr.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.mfin.bom.factory.CustomerInformationFactory;
import com.mfin.bom.factory.FinanceInformationFactory;
import com.mfin.bom.factory.LoanMasterFactory;
import com.mfin.bom.factory.UserInformationFactory;
import com.mfin.bom.factory.interfaces.ICustomerInformationFactory;
import com.mfin.bom.factory.interfaces.IFinanceInformationFactory;
import com.mfin.bom.factory.interfaces.ILoanMasterFactory;
import com.mfin.bom.factory.interfaces.IUserInformationFactory;
import com.mfin.bom.interfaces.ICustomer;
import com.mfin.bom.interfaces.IDocCharge;
import com.mfin.bom.interfaces.IFinance;
import com.mfin.bom.interfaces.IFinanceLoan;
import com.mfin.bom.interfaces.ILoanMaster;
import com.mfin.bom.interfaces.ILoanPreference;
import com.mfin.bom.interfaces.IPartner;
import com.mfin.bom.interfaces.IVehicle;
import com.mfin.bs.mgr.interfaces.ILoanMasterManager;
import com.mfin.enumeration.LoanType;
import com.mfin.vo.CustomerVO;
import com.mfin.vo.PartnerVO;
import com.mfin.vo.finance.FinanceVO;
import com.mfin.vo.loan.DocChargeListVO;
import com.mfin.vo.loan.DocChargeVO;
import com.mfin.vo.loan.FinanceLoanVO;
import com.mfin.vo.loan.LoanApplicationVO;
import com.mfin.vo.loan.LoanMasterVO;
import com.mfin.vo.loan.LoanPreferenceVO;
import com.mfin.vo.loan.VehicleVO;

public class LoanMasterManager extends BaseManager implements
		ILoanMasterManager {

	ICustomerInformationFactory customerInformationFactory = new CustomerInformationFactory();
	IFinanceInformationFactory financeInformationFactory = new FinanceInformationFactory();
	IUserInformationFactory userInformationFactory = new UserInformationFactory();
	ILoanMasterFactory loanMasterFactory = new LoanMasterFactory();

	@Override
	public FinanceLoanVO createLoan(FinanceVO financeVO,
			LoanApplicationVO loanApplicationVO) {
		logMethodBegin("LoanMasterManager", "createLoan");
		financeInformationFactory
				.setPersistenceGovernor(getPersistenceGovernor());
		customerInformationFactory
				.setPersistenceGovernor(getPersistenceGovernor());
		userInformationFactory.setPersistenceGovernor(getPersistenceGovernor());
		loanMasterFactory.setPersistenceGovernor(getPersistenceGovernor());

		CustomerVO customerVO = loanApplicationVO.getCustomer();
		PartnerVO partnerVO = loanApplicationVO.getPartner();
		LoanType loanType = loanApplicationVO.getLoanType();
		VehicleVO vehicleVO = loanApplicationVO.getVehicle();

		IFinance bomFinance = financeInformationFactory
				.getFinanceInformation(financeVO);
		IFinanceLoan bomLoan = customerInformationFactory
				.createLoan(customerVO);
		ICustomer bomCustomer = customerInformationFactory
				.getCustomerInformation(customerVO);
		IPartner bomPartner = customerInformationFactory
				.getPartnerInformation(partnerVO);
		ILoanMaster bomLoanmaster = loanMasterFactory.getLoanMaster(loanType);

		map(loanApplicationVO, bomLoan, false, false);

		bomLoan.setFinance(bomFinance);
		bomLoan.setCustomer(bomCustomer);
		bomLoan.setPartner(bomPartner);
		bomLoan.setLoanMaster(bomLoanmaster);

		if (vehicleVO != null) {
			IVehicle bomVehicle = loanMasterFactory.createVehicle();
			map(vehicleVO, bomVehicle, false, false);
		}

		if (loanApplicationVO.getGuarantors() != null) {
			CustomerVO[] customers = loanApplicationVO.getGuarantors()
					.getCustomers();

			Set<ICustomer> guarantorSet = new HashSet<ICustomer>();
			for (CustomerVO guarantor : customers) {
				ICustomer bomGuarantor = customerInformationFactory
						.getCustomerInformation(guarantor);
				guarantorSet.add(bomGuarantor);
			}
			bomLoan.setGuarantors(guarantorSet);
		}

		FinanceLoanVO loanVO = new FinanceLoanVO();
		map(bomLoan, loanVO, false, true);

		logMethodEnd("LoanMasterManager", "createLoan");
		return loanVO;
	}

	@Override
	public LoanType[] getAllLoanTypes() {
		logMethodBegin("LoanMasterManager", "getAllLoanTypes");

		loanMasterFactory.setPersistenceGovernor(getPersistenceGovernor());

		List<ILoanMaster> bomLoanmasterList = loanMasterFactory
				.getAllLoanTypes();

		LoanType[] loanTypes = null;

		if (bomLoanmasterList != null) {
			loanTypes = new LoanType[bomLoanmasterList.size()];
			int index = 0;
			for (ILoanMaster bomLoanMaster : bomLoanmasterList) {
				loanTypes[index++] = bomLoanMaster.getLoanType();
			}
		}
		logMethodEnd("LoanMasterManager", "getAllLoanTypes");
		return loanTypes;

	}

	@Override
	public LoanPreferenceVO getLoanPreference(FinanceVO financeVO,
			LoanType loanType) {
		logMethodBegin("LoanMasterManager", "getLoanPreference");
		loanMasterFactory.setPersistenceGovernor(getPersistenceGovernor());

		ILoanPreference bomLoanPreference = loanMasterFactory
				.getFinanceLoanPreference(financeVO, loanType);

		LoanPreferenceVO loanPreferenceVO = new LoanPreferenceVO();
		map(bomLoanPreference, loanPreferenceVO, false, true);
		logMethodEnd("LoanMasterManager", "getLoanPreference");
		return loanPreferenceVO;
	}

	@Override
	public LoanMasterVO addLoanMaster(LoanMasterVO loanMasterVO) {
		logMethodBegin("LoanMasterManager", "addLoanMaster");
		loanMasterFactory.setPersistenceGovernor(getPersistenceGovernor());

		ILoanMaster bomLoanMaster = loanMasterFactory
				.createLoanMaster(loanMasterVO.getLoanType());

		map(loanMasterVO, bomLoanMaster, false, false);
		map(bomLoanMaster, loanMasterVO, false, true);
		logMethodEnd("LoanMasterManager", "addLoanMaster");
		return loanMasterVO;
	}

	@Override
	public void addFinanceLoanPreference(FinanceVO financeVO,
			LoanPreferenceVO loanPreferenceVO) {
		logMethodBegin("FinanceInformationManager", "addFinanceLoanPreference");

		financeInformationFactory
				.setPersistenceGovernor(getPersistenceGovernor());
		loanMasterFactory.setPersistenceGovernor(getPersistenceGovernor());
		IFinance bomFinance = financeInformationFactory
				.getFinanceInformation(financeVO);

		LoanType loanType = loanPreferenceVO.getLoanType();
		ILoanMaster bomLoanMaster = loanMasterFactory.getLoanMaster(loanType);

		ILoanPreference bomLoanPreference = loanMasterFactory
				.createLoanPreference(bomFinance, bomLoanMaster);

		map(loanPreferenceVO, bomLoanPreference, false, false);

		DocChargeListVO docChargeListVO = loanPreferenceVO.getDocChargeList();

		if (docChargeListVO != null) {
			DocChargeVO[] docCharges = docChargeListVO.getDocCharges();
			List<IDocCharge> bomDocCharges = new ArrayList<IDocCharge>();

			if (docCharges != null) {
				for (DocChargeVO docChargeVO : docCharges) {
					IDocCharge bomDocCharge = loanMasterFactory.createDocCharge();
					bomDocCharge.setLoanPreference(bomLoanPreference);
					map(docChargeVO, bomDocCharge, false, false);
					bomDocCharges.add(bomDocCharge);
				}
			}
			bomLoanPreference.setDocCharges(bomDocCharges);
		}

		map(bomLoanPreference, loanPreferenceVO, false, true);

		logMethodEnd("FinanceInformationManager", "addFinanceLoanPreference");
	}

	@Override
	public void updateFinanceLoanPreference(LoanPreferenceVO loanPreferenceVO) {

		logMethodBegin("FinanceInformationManager", "addFinanceLoanPreference");

		financeInformationFactory
				.setPersistenceGovernor(getPersistenceGovernor());
		loanMasterFactory.setPersistenceGovernor(getPersistenceGovernor());

		ILoanPreference bomLoanPreference = loanMasterFactory
				.getFinanceLoanPreference(loanPreferenceVO);

		map(loanPreferenceVO, bomLoanPreference, false, false);

		loanMasterFactory.deleteDocChargeList(bomLoanPreference.getDocCharges());
		DocChargeListVO docChargeListVO = loanPreferenceVO.getDocChargeList();

		if (docChargeListVO != null) {
			DocChargeVO[] docCharges = docChargeListVO.getDocCharges();
			List<IDocCharge> bomDocCharges = new ArrayList<IDocCharge>();

			if (docCharges != null) {
				for (DocChargeVO docChargeVO : docCharges) {
					IDocCharge bomDocCharge = loanMasterFactory.createDocCharge();
					bomDocCharge.setLoanPreference(bomLoanPreference);
					map(docChargeVO, bomDocCharge, false, false);
					bomDocCharges.add(bomDocCharge);
				}
			}
			bomLoanPreference.setDocCharges(bomDocCharges);
		}

		map(bomLoanPreference, loanPreferenceVO, false, true);

		logMethodEnd("FinanceInformationManager", "addFinanceLoanPreference");
	
	}
}
